package com.itc.bpm.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itc.bi.api.BiService;
import com.itc.bpm.bean.BpmModel;
import com.itc.bpm.bean.BpmProcessCategory;
import com.itc.bpm.bean.BpmProcessInstanceExt;
import com.itc.bpm.bean.BpmProcessTaskExt;
import com.itc.bpm.dto.*;
import com.itc.bpm.framework.factory.vo.BpmStartVO;
import com.itc.bpm.framework.factory.vo.dto.BpmTaskDto;
import com.itc.bpm.framework.service.ProcessInstanceService;
import com.itc.bpm.service.BpmModelService;
import com.itc.bpm.service.BpmProcessCategoryService;
import com.itc.bpm.service.BpmProcessInstanceExtService;
import com.itc.bpm.service.BpmProcessTaskExtService;
import com.itc.bpm.vo.BpmCurrentUserTask;
import com.itc.bpm.vo.BpmProcessUpVo;
import com.itc.bpm.vo.BpmTaskRebackVo;
import com.itc.bpm.vo.BpmUserTaskVo;
import com.itc.common.core.domain.R;
import com.itc.common.log.annotation.Log;
import com.itc.common.log.enums.BusinessType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "流程实例控制-流程中心")
@RestController
@RequestMapping("/bpm/factory")
public class BpmFactorController {

    @Autowired
    private ProcessInstanceService processInstanceService;


    @Autowired
    BpmProcessTaskExtService bpmProcessTaskExtService;

    @Autowired
    BpmProcessInstanceExtService bpmProcessInstanceExtService;

    @Autowired
    BpmModelService bpmModelService;


    @Autowired
    BpmProcessCategoryService bpmProcessCategoryService;
    @PostMapping("/createProcess")
    @Log(title = "开启流程实例任务",businessType = BusinessType.OTHER)
    @ApiOperation(value = "开启流程实例任务")
    public R<String> createProcessInstance(@RequestBody @Validated BpmStartVO bpmStartVO){
        return processInstanceService.createProcessInstance(bpmStartVO);
    }

    @GetMapping("/cancelProcess/{processInstanceId}")
    @Log(title = "关闭流程实例任务",businessType = BusinessType.OTHER)
    @ApiOperation(value = "关闭流程实例任务")
    public R<String> cancelProcessInstance(@PathVariable("processInstanceId") String processInstanceId){
        return processInstanceService.cacenProcessInstance(processInstanceId);
    }

    @GetMapping("/claimTask/{taskId}")
    @Log(title = "认领任务",businessType = BusinessType.OTHER)
    @ApiOperation(value = "认领任务")
    public R<String> claimTask(@PathVariable("taskId") String taskId){
        return bpmProcessTaskExtService.claimTask(taskId);
    }
    //
    @PostMapping("/commitTask")
    @Log(title = "保存/提交任务",businessType = BusinessType.OTHER)
    @ApiOperation(value = "保存/提交任务")
    public R<String> commitTask(@RequestBody @Validated BpmUserTaskVo bpmStartVO){
        return bpmProcessTaskExtService.commitTask(bpmStartVO);
    }

    @PostMapping("/findOurTasks")
    @ApiOperation(value = "根据流程实例查询待处理任务列表")
    public R<List<BpmUserTaskDto>> findOurTasks(@RequestBody BpmCurrentUserTask task){
        return bpmProcessTaskExtService.findOurTasks(task);
    }

    //
    @GetMapping("/history/record/{processInstanceId}")
    @Log(title = "流程历史填报记录",businessType = BusinessType.OTHER)
    @ApiOperation(value = "流程历史填报记录")
    public R<List<BpmHistoryTaskDto>> historyTaskRecord(@PathVariable("processInstanceId") String processInstanceId){
        return bpmProcessTaskExtService.historyTaskRecord(processInstanceId);
    }
    @GetMapping("/getTaskListByProcessInstanceId/{processInstanceId}")
    @ApiOperation(value = "流程详情")
    public R<BpmViewDto> getTaskListByProcessInstanceId(@PathVariable("processInstanceId") String processInstanceId){
        return bpmProcessTaskExtService.getTaskListByProcessInstanceId(processInstanceId);
    }

    @GetMapping("/countProcessInstanceInfo/{processInstanceId}")
    @ApiOperation(value = "流程中中心按分类统计 流程完成情况")
    public R<List<BpmFactoryCountDto>> countProcessInstanceInfo(){
        return bpmProcessInstanceExtService.countProcessInstanceInfo();
    }

    @PostMapping("/page")
    @ApiOperation(value = "流程中心分页")
    public R<Page<BpmProcessInstanceExt>> getPage(@RequestBody BpmProcessInstanceExt bpmFormDesign)
    {
        Page<BpmProcessInstanceExt> page = new Page<>();
        page.setOptimizeCountSql(true);
        page.setSize(bpmFormDesign.getSize());
        page.setCurrent(bpmFormDesign.getCurrent());
        bpmFormDesign.setDelFlag(0);
        Date endTime = bpmFormDesign.getEndTime();
        bpmFormDesign.setEndTime(null);
        //bpmFormDesign.setStatus(0);
        LambdaQueryWrapper<BpmProcessInstanceExt> queryWrapper = new LambdaQueryWrapper<>(bpmFormDesign);
        if(bpmFormDesign.getStartTime()!=null){
            queryWrapper.ge(BpmProcessInstanceExt::getCreateTime,bpmFormDesign.getStartTime());
        }
        if(endTime!=null){
            queryWrapper.le(BpmProcessInstanceExt::getCreateTime,endTime);
        }

        queryWrapper.orderByDesc(BpmProcessInstanceExt::getCreateTime);
        Page<BpmProcessInstanceExt> resultPage = bpmProcessInstanceExtService.page(page,queryWrapper);
        return R.ok(resultPage);
    }


    @PostMapping("/upDwon/process")
    @ApiOperation(value = "流程中心升降级")
    public R upDwon(@RequestBody BpmProcessUpVo bpmFormDesign)
    {
        return bpmProcessInstanceExtService.upDwon(bpmFormDesign);
    }

    @GetMapping("/taskRecord/{processInstanceId}")
    @ApiOperation(value = "根据流程流程操作记录")
    public R<List<BpmProcessTaskExt>> taskRecord(@PathVariable("processInstanceId") String processInstanceId){
         List<BpmProcessTaskExt> list = bpmProcessTaskExtService.list(new LambdaQueryWrapper<BpmProcessTaskExt>().eq(BpmProcessTaskExt::getProcessInstanceId,processInstanceId).orderByAsc(BpmProcessTaskExt::getCreateTime));
         return R.ok(list);
    }

    @PostMapping("/rebackBpmTask")
    @ApiOperation(value = "驳回任务数据记录")
    public R rebackBpmTask(@Validated @RequestBody BpmTaskRebackVo rebackVo){
        return bpmProcessTaskExtService.rebackBpmTask(rebackVo);
    }


    // 查询当前业务已启动哪些业务流程

    /**
     *
     * @return
     */
    @PostMapping("/serviceTaskPag")
    @ApiOperation(value = "流程根据业务情况获取分页")
    public R<Page<BpmProcessInstanceExt>> getServiceTaskPage(@RequestBody BpmServiceDto dto)
    {
        if(dto.getStatus()==0){
            BpmProcessInstanceExt bpmFormDesign = new BpmProcessInstanceExt();
            Page<BpmProcessInstanceExt> page = new Page<>();
            page.setOptimizeCountSql(true);
            page.setSize(dto.getSize());
            page.setCurrent(dto.getCurrent());
            bpmFormDesign.setDelFlag(0);
            bpmFormDesign.setServiceId(dto.getServiceId());
            //bpmFormDesign.setStatus(0);
            LambdaQueryWrapper<BpmProcessInstanceExt> queryWrapper = new LambdaQueryWrapper<>(bpmFormDesign);

            queryWrapper.orderByDesc(BpmProcessInstanceExt::getCreateTime);
            Page<BpmProcessInstanceExt> resultPage = bpmProcessInstanceExtService.page(page,queryWrapper);
            return R.ok(resultPage);
        }else{ // 全部业务类型
            BpmModel bpmModel = new BpmModel();
            List<String> categorys = null;
            List<BpmProcessCategory> list = bpmProcessCategoryService.list(new LambdaQueryWrapper<BpmProcessCategory>().eq(BpmProcessCategory::getType,dto.getType()));
            if(list!=null && list.size()>0){
                categorys = list.stream().map(BpmProcessCategory::getCode).collect(Collectors.toList());
            }
            bpmModel.setDelFlag(0);
            bpmModel.setStatus(0);
            bpmModel.setIsDeploy(1);
            LambdaQueryWrapper<BpmModel> bpmModelLambdaQueryWrapper = new LambdaQueryWrapper<>(bpmModel);
            if(categorys!=null && categorys.size()>0){
                bpmModelLambdaQueryWrapper.in(BpmModel::getCategory,categorys);
            }
            Page<BpmModel> page = new Page<>();
            page.setOptimizeCountSql(true);
            page.setSize(dto.getSize());
            page.setCurrent(dto.getCurrent());
            Page<BpmModel> modelPage = bpmModelService.page(page,bpmModelLambdaQueryWrapper);
            List<BpmProcessInstanceExt> bpmProcessInstanceExts = new ArrayList<>();
            if(modelPage!=null && modelPage.getRecords()!=null && modelPage.getRecords().size()>0){
                List<BpmModel> models = modelPage.getRecords();
                for(BpmModel item:models){
                    BpmProcessInstanceExt ext = new BpmProcessInstanceExt();
                    ext.setBpmModelId(item.getId());
                    ext.setName(item.getBpmName());
                    ext.setCreateTime(item.getDeployDate());
                    ext.setVersion(item.getVersion());
                    ext.setBpmKey(item.getBpmKey());
                    ext.setCategory(item.getCategory());
                    BpmProcessInstanceExt processInstanceExt = bpmProcessInstanceExtService.findModelByModelKey(item.getBpmKey(),dto.getServiceId());
                    if(processInstanceExt!=null){
                        bpmProcessInstanceExts.add(processInstanceExt);
                    }else{
                        ext.setStatus(-1);
                        bpmProcessInstanceExts.add(ext);
                    }
                }
            }
            Page<BpmProcessInstanceExt> extPage = new Page<>();
            extPage.setCurrent(page.getCurrent());
            extPage.setSize(page.getSize());
            extPage.setTotal(page.getTotal());
            extPage.setRecords(bpmProcessInstanceExts);
            return R.ok(extPage);
        }

    }

    @GetMapping("/getEvent/{type}")
    @ApiOperation(value = "获取重要事件未结束流程 type 0 重要事件待办流程 1 重要事件全部流程 2全部待办")
    public R<List<BpmProcessInstanceExt>> getImportantEvent(@PathVariable("type") Integer type){
        BpmProcessInstanceExt processInstanceExt = new BpmProcessInstanceExt();
        processInstanceExt.setDelFlag(0);
        if(type==0){
            processInstanceExt.setIsImportantEvent(1);
            processInstanceExt.setStatus(0);
        }else if(type==1){
            processInstanceExt.setIsImportantEvent(1);
        }else if(type==2){
            processInstanceExt.setStatus(0);
        }
        LambdaQueryWrapper<BpmProcessInstanceExt> queryWrapper = new LambdaQueryWrapper<>(processInstanceExt).orderByDesc(BpmProcessInstanceExt::getCreateTime);
        List<BpmProcessInstanceExt> processInstanceExts = bpmProcessInstanceExtService.list(queryWrapper);
        return R.ok(processInstanceExts);
    }



}
